package com.ar4j;

import java.lang.reflect.Method;
import java.util.Collections;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;
import org.springframework.transaction.interceptor.TransactionAttribute;

import com.ar4j.handler.IMethodHandler;
import com.ar4j.type.ITypeConverter;

/**
 * Holds meta data about an active record domain class
 */
public final class ActiveRecordMetadata {
  private String factoryName;
  private Class<?> baseClass;
  private Set<String> propertyNames;
  private Map<String, Class<?>> propertyTypeMap;
  private Map<Method, IMethodHandler> methodHandlerMap;
  private Map<String, Method> propertyReadMethods;
  private Map<String, Method> propertyWriteMethods;
  private String tableName;
  private String identifierPropertyName;
  private Set<String> propertiesAutogeneratedInBackingStore;
  private Map<String, ITypeConverter<?, ?>> propertyTypeConvertorMap;
  private Map<String, String> propertyColumnNameMap;
  private Set<String> backingStoreReadableProperties;
  private Set<String> backingStoreWritableProperties;
  private Map<Method, TransactionAttribute> methodTransactionAttributeMap;
  
  public String getFactoryName() {
    return factoryName;
  }

  public Class<?> getBaseClass() {
    return baseClass;
  }

  public Set<String> getPropertyNames() {
    return propertyNames;
  }
  
  public Map<String, Class<?>> getPropertyTypeMap() {
    return propertyTypeMap;
  }

  public Map<Method, IMethodHandler> getMethodHandlerMap() {
    return methodHandlerMap;
  }
  
  public Map<String, Method> getPropertyReadMethods() {
    return propertyReadMethods;
  }

  public Map<String, Method> getPropertyWriteMethods() {
    return propertyWriteMethods;
  }
  
  public String getTableName() {
    return tableName;
  }

  public String getIdentifierPropertyName() {
    return identifierPropertyName;
  }
  
  public Set<String> getPropertiesAutogeneratedInBackingStore() {
    return propertiesAutogeneratedInBackingStore;
  }
  
  public Map<String, ITypeConverter<?, ?>> getPropertyTypeConvertorMap() {
    return propertyTypeConvertorMap;
  }
  
  public Map<String, String> getPropertyColumnNameMap() {
    return propertyColumnNameMap;
  }
  
  public Set<String> getBackingStoreReadableProperties() {
    return backingStoreReadableProperties;
  }

  public Set<String> getBackingStoreWritableProperties() {
    return backingStoreWritableProperties;
  }
  
  public Map<Method, TransactionAttribute> getMethodTransactionAttributeMap() {
    return methodTransactionAttributeMap;
  }

  protected void setFactoryName(String factoryName) {
    this.factoryName = factoryName;
  }

  protected void setBaseClass(Class<?> baseClass) {
    this.baseClass = baseClass;
  }
  
  protected void setPropertyNames(Set<String> propertyNames) {
    this.propertyNames = propertyNames;
  }
  
  protected void setPropertyTypeMap(Map<String, Class<?>> propertyTypeMap) {
    this.propertyTypeMap = Collections.unmodifiableMap(propertyTypeMap);
  }
  
  protected void setMethodHandlerMap(Map<Method, IMethodHandler> methodHandlerMap) {
    this.methodHandlerMap = Collections.unmodifiableMap(methodHandlerMap);
  }
  
  protected void setPropertyReadMethods(Map<String, Method> propertyReadMethods) {
    this.propertyReadMethods = Collections.unmodifiableMap(propertyReadMethods);
  }
  
  protected void setPropertyWriteMethods(Map<String, Method> propertyWriteMethods) {
    this.propertyWriteMethods = Collections.unmodifiableMap(propertyWriteMethods);
  }
  
  protected void setTableName(String tableName) {
    this.tableName = tableName;
  }
  
  protected void setIdentifierPropertyName(String identifierPropertyName) {
    this.identifierPropertyName = identifierPropertyName;
  }
  
  protected void setPropertiesAutogeneratedInBackingStore(Set<String> propertiesAutogeneratedInBackingStore) {
    this.propertiesAutogeneratedInBackingStore = propertiesAutogeneratedInBackingStore;
  }
  
  protected void setPropertyTypeConvertorMap(Map<String, ITypeConverter<?, ?>> propertyTypeConvertorMap) {
    this.propertyTypeConvertorMap = propertyTypeConvertorMap;
  }
  
  protected void setPropertyColumnNameMap(Map<String, String> propertyColumnNameMap) {
    this.propertyColumnNameMap = propertyColumnNameMap;
  }
  
  protected void setBackingStoreReadableProperties(Set<String> backingStoreReadableProperties) {
    this.backingStoreReadableProperties = backingStoreReadableProperties;
  }
  
  protected void setBackingStoreWritableProperties(Set<String> backingStoreWritableProperties) {
    this.backingStoreWritableProperties = backingStoreWritableProperties;
  }
  
  protected void setMethodTransactionAttributeMap(Map<Method, TransactionAttribute> methodTransactionAttributeMap) {
    this.methodTransactionAttributeMap = methodTransactionAttributeMap;
  }
  
  @Override
  public String toString() {
    return ToStringBuilder.reflectionToString(this, ToStringStyle.SHORT_PREFIX_STYLE);
  }
  
}
